// utils/bluetooth.js
class BluetoothManager {
	constructor(store) {
		this.store = store;
		this.deviceMap = {}; // 扫描缓存
		this.isDiscovering = false; // 扫描状态
		this.connectedDevices = {}; // 已连接设备池 { deviceId: {name, connected} }
		// 新增：内存缓存别名映射表（初始化时读取一次）
		this.aliasMap = this.getAliasMap(); // 关键：首次加载时缓存到内存

		this.initListeners(); // 初始化全局监听
	}

	/** ===================== 初始化全局监听 ===================== */
	initListeners() {

		// 监听蓝牙适配器状态变化
		uni.onBluetoothAdapterStateChange(res => {
			console.log("📡 蓝牙适配器状态变化:", res);
			this.store.commit('bluetooth/SET_ADAPTER_STATE', res);
		});

		// 监听设备连接状态变化
		uni.onBLEConnectionStateChange(res => {
			const {
				deviceId,
				connected
			} = res;
			console.log("🔗 蓝牙连接状态变化:", res);

			if (this.connectedDevices[deviceId]) {
				this.connectedDevices[deviceId].connected = connected;
			}

			this.store.commit('bluetooth/UPDATE_CONNECTION', {
				deviceId,
				connected
			});
			console.log(this.store.getters["bluetooth/getConnectedDevices"]);

			if (connected) {
				this.enableNotify(deviceId);
			}
		});

		// 监听蓝牙特征值变化（接收数据）
		uni.onBLECharacteristicValueChange(async (res) => {
			console.log(res);
			const hex = this.ab2hex(res.value);


			// console.log(`📩 收到(${res.deviceId})数据:`, hex);
			console.log(hex);
			// 获取当前蓝牙的协议信息
			const deviceInfo = await this.store.state.bluetooth.connectedDevices[res.deviceId];

			// 根据蓝牙协议处理蓝牙数据
			let backData = await this.getDataByBluetoothProtocol(hex, deviceInfo.config
				.BluetoothProtocol);
			console.log(backData);
			// 发送数据
			uni.$emit("bluetooth:get_device_data", {
				num: backData,
				deviceInfo
			})
			// this.store.commit('bluetooth/ADD_MESSAGE', {
			// 	deviceId: res.deviceId,
			// 	data: backData
			// });
		});
	}

	getDataByBluetoothProtocol(hexStr, BluetoothProtocol) {
		let parsedValue = null;
		let dataHex = null;
		let dataDec = null;

		switch (BluetoothProtocol) {
			case "YBKC_Sanhe_5101": // 三和游标卡尺
				dataHex = hexStr.slice(8); // 后8位数据区
				console.log("原始HEX:", dataHex);
				let str = dataHex.substring(dataHex.length - 2);
				// 截取有效的 3 字节（低 3 字节为数据，高位可能是符号）
				let raw = parseInt(dataHex.slice(0, 6), 16); // 取 3 字节数据
				if (raw & 0x800000) { // 判断 24 位符号位
					raw = raw - 0x1000000;
				}

				dataDec = raw;
				console.log("解析DEC:", dataDec);
				// parsedValue = dataDec / 25600; // 转实际测量值
				if (str == '01') {
					parsedValue = 0 - (dataDec / 100)
				} else {
					parsedValue = dataDec / 100;
				}
				break;

			case "QFB_Sanhe_001": // 三和千分表
				dataHex = hexStr.slice(8);
				let str2 = dataHex.substring(dataHex.length - 2);
				let raw2 = parseInt(dataHex.slice(0, 6), 16);
				if (raw2 & 0x800000) {
					raw2 = raw2 - 0x1000000;
				}
				dataDec = raw2;
				console.log(dataDec);
				// parsedValue = dataDec / 2560000;
				if (str2 == '01') {
					parsedValue = 0 - (dataDec / 10000)
				} else {
					parsedValue = dataDec / 10000;
				}
				break;

			default:
				parsedValue = null;
				break;
		}

		return parsedValue;
	}


	parseCaliperData(buffer) {
		// 转成16进制字符串数组
		const data = Array.prototype.map.call(new Uint8Array(buffer), x => x.toString(16).padStart(2, '0'));
		if (data[0] !== '02') return null; // 校验帧头

		const signFlag = data[1]; // 00正 01负
		const unitFlag = data[2]; // ff毫米 00英寸
		const valueHex = data[3] + data[4] + data[5] + data[6]; // 数据区(低位在前)

		// 小端转大端
		const realHex = data.slice(3, 7).reverse().join('');
		const rawValue = parseInt(realHex, 16);

		let value = rawValue / 100; // 每单位=0.01mm
		if (signFlag === '01') value = -value;

		const unit = unitFlag === 'ff' ? 'mm' : 'inch';
		return {
			value,
			unit
		};
	}


	/** ===================== 初始化蓝牙 ===================== */
	openBluetooth() {
		return new Promise((resolve, reject) => {
			uni.openBluetoothAdapter({
				success: res => {
					console.log("✅ 蓝牙适配器已初始化");
					this.store.commit('bluetooth/SET_ADAPTER_OPEN', true);
					resolve({
						...res,
						status: 0
					});
				},
				fail: err => {
					console.error("❌ 初始化失败:", err);
					uni.showToast({
						title: "请打开蓝牙权限",
						icon: "none"
					});
					reject(err);
				}
			});
		});
	}

	/** ===================== 蓝牙扫描 ===================== */
	/**
	 * 开始扫描设备
	 * @param {Function} callback - 每次发现设备时执行的回调函数，参数为原始 res
	 */
	startDiscovery(callback, option = {
		allowDuplicatesKey: true
	}) {
		if (this.isDiscovering) {
			console.warn("⚠️ 正在扫描中");
			return;
		}
		this.isDiscovering = true;
		this.deviceMap = {};
		this.store.commit('bluetooth/CLEAR_DEVICES');
		// this.stopDiscovery();


		uni.onBluetoothDeviceFound(res => {
			const devices = res.devices || [res.device] || [];
			const valid = devices.filter(d => d.name && d.localName);
			callback && callback(valid);
		});

		uni.startBluetoothDevicesDiscovery({
			allowDuplicatesKey: true,
			success: () => {
				console.log("✅ 开始扫描蓝牙设备");


				// ✅ 返回 stop 方法给调用方
				this.stopDiscovery = () => {
					console.log("🛑 停止扫描");
					this.isDiscovering = false;
					uni.stopBluetoothDevicesDiscovery();
					// uni.offBluetoothDeviceFound(handler);
				};
			},
			fail: err => {
				console.error("❌ 扫描失败:", err);
				this.isDiscovering = false;
			}
		});
	}


	/** 停止扫描 */
	stopDiscovery() {
		console.log(this.isDiscovering);
		if (!this.isDiscovering) return;
		uni.stopBluetoothDevicesDiscovery({
			success: () => {
				console.log("🛑 停止扫描");
				this.isDiscovering = false;
				// uni.offBluetoothDeviceFound();
			}
		});
	}

	/** 监听发现设备 */
	listenDeviceFound(callback) {
		uni.onBluetoothDeviceFound(res => {
			// 某些平台返回 res.devices（数组），某些直接返回 res.device（对象）
			const devices = res.devices || [res.device] || [];

			// 过滤掉没有名称的设备
			const validDevices = devices.filter(d => d.name || d.localName);

			// 回调返回过滤后的列表
			callback && callback(validDevices);
		});

	}

	/** 主动移除设备监听 */
	removeDeviceListener() {
		// uni.offBluetoothDeviceFound();
	}

	/** ===================== 连接与断开 ===================== */
	/**
	 * 连接蓝牙设备
	 * @param {Object} device - 蓝牙设备对象
	 * @param {Object} basicInfo 选中的设备协议
	 */
	connectDevice(device, basicInfo, successCallback, failCallBack) {
		if (!device.deviceId) return;
		const {
			deviceId
		} = device;
		console.log(`🔗 尝试连接设备: ${deviceId}`);

		uni.createBLEConnection({
			deviceId,
			success: res => {
				console.log(`✅ 连接成功: ${deviceId}`);
				// this.connectedDevices[deviceId] = {
				// 	...device,
				// 	config: basicInfo,
				// 	connected: true,
				// 	connectedAt: Date.now()
				// };
				const aliasName = this.getDeviceAlias(deviceId); // 自动加载别名

				this.connectedDevices[deviceId] = {
					...device,
					config: basicInfo,
					connected: true,
					connectedAt: Date.now(),
					aliasName: aliasName || device.name // 优先别名
				};

				this.store.commit('bluetooth/ADD_CONNECTED_DEVICE', this.connectedDevices[deviceId]);

				this.stopDiscovery(); // 自动停止扫描，可视情况注释
				successCallback && successCallback();
			},
			fail: err => {
				failCallBack && failCallBack(err);
				console.error(`❌ 连接失败 (${deviceId}):`, err);
				uni.showToast({
					title: "连接失败",
					icon: "none"
				});
			}
		});
	}

	/** ===================== 查询指定设备连接状态 ===================== */
	isConnected(deviceId) {
		if (!deviceId) return false;

		// ① 内存快速判断
		const localStatus = this.connectedDevices[deviceId]?.connected;
		if (localStatus) return true;

		// ② 如果内存中无记录，查系统层状态（异步）
		return new Promise((resolve) => {
			uni.getConnectedBluetoothDevices({
				success: res => {
					const found = res.devices.some(d => d.deviceId === deviceId);
					resolve(found);
				},
				fail: () => resolve(false)
			});
		});
	}


	/**
	 * 断开指定设备
	 * @param {String} deviceId - 要断开的设备ID
	 */
	disconnectDevice(deviceId, callBack) {
		if (!deviceId) {
			uni.showToast({
				title: "无效设备ID",
				icon: "none"
			});
			return;
		}

		uni.closeBLEConnection({
			deviceId,
			success: () => {
				console.log(`🛑 已断开设备: ${deviceId}`);
				// ✅ 不删除，只修改连接状态
				this.store.commit('bluetooth/UPDATE_CONNECTION', {
					deviceId,
					connected: false
				});

				callBack && callBack()
			},
			fail: err => {
				console.error(`❌ 断开失败 (${deviceId}):`, err);
			}
		});
	}
	destroyListeners() {
		uni.offBluetoothAdapterStateChange();
		uni.offBLEConnectionStateChange();
		uni.offBLECharacteristicValueChange();
		// uni.offBluetoothDeviceFound();
		console.log("🧹 蓝牙全局监听已清理");
	}

	/** ===================== 本地别名管理 ===================== */

	/** 从内存缓存获取别名映射表 */
	getAliasMap() {
		try {
			// 优先用内存缓存，没有则读本地存储并初始化缓存
			return this.aliasMap || JSON.parse(uni.getStorageSync('bluetooth_alias_map') || '{}');
		} catch (e) {
			return {};
		}
	}

	/** 保存别名时同步更新内存缓存 */
	saveAliasMap(map) {
		try {
			this.aliasMap = map; // 同步更新内存
			uni.setStorageSync('bluetooth_alias_map', JSON.stringify(map));
		} catch (e) {
			console.error('保存别名失败:', e);
		}
	}

	// 从内存缓存获取别名（性能最优）
	getDeviceAlias(deviceId) {
		return this.aliasMap[deviceId] || null; // 直接读内存，无需IO操作
	}

	/** 设置指定设备的别名 */
	setDeviceAlias(deviceId, aliasName) {
		if (!deviceId) return;
		const aliasMap = this.getAliasMap();
		aliasMap[deviceId] = aliasName;
		this.saveAliasMap(aliasMap);

		// 同步更新 store / 内存
		if (this.connectedDevices[deviceId]) {
			this.connectedDevices[deviceId].aliasName = aliasName;
		}

		this.store.commit('bluetooth/UPDATE_DEVICE_ALIAS', {
			deviceId,
			aliasName
		});
	}



	/** ===================== 启用通知 ===================== */
	enableNotify(deviceId) {
		if (!deviceId) return;
		// if (this.connectedDevices[deviceId]?.notifying) {
		// 	console.log(`ℹ️ 已开启通知监听(${deviceId})，跳过重复操作`);
		// 	return;
		// }
		this.connectedDevices[deviceId].notifying = true;

		setTimeout(() => {
			uni.getBLEDeviceServices({
				deviceId,
				success: res => {
					const services = res.services.filter(s => s.isPrimary).slice().reverse();
					console.log(services);
					this.subscribeNext(deviceId, services, 0);
				},
				fail: e => console.error(`❌ 获取服务失败(${deviceId})`, e)
			});
		}, 300);
	}


	subscribeNext(deviceId, services, index) {
		if (index >= services.length) return;
		
		console.log({
			deviceId,
			serviceId: services[index].uuid,
		});
		uni.getBLEDeviceCharacteristics({
			deviceId,
			serviceId: services[index].uuid,
			success: res => {
				const chars = res.characteristics || [];
				for (let c of chars) {
					if (c.properties.notify) {
						uni.notifyBLECharacteristicValueChange({
							state: true,
							deviceId,
							serviceId: services[index].uuid,
							characteristicId: c.uuid,
							success: () => console.log(`✅ 启用通知(${deviceId})`),
						});
					}
				}
				this.subscribeNext(deviceId, services, index + 1);
			},
			fail: e => console.error("❌ 获取特征失败:", e)
		});
	}

	/** ===================== 工具函数 ===================== */
	hex2Bytes(hexStr) {
		let pos = 0;
		let len = hexStr.length;
		if (len % 2 != 0) return null;

		len /= 2;
		let hexA = [];
		for (let i = 0; i < len; i++) {
			let s = hexStr.substr(pos, 2);
			let v = parseInt(s, 16);
			hexA.push(v);
			pos += 2;
		}
		return hexA;
	}
	ab2hex(buffer) {
		return Array.from(new Uint8Array(buffer))
			.map(b => ("00" + b.toString(16)).slice(-2))
			.join("");
	}
}

/** 单例导出 */
let instance = null;
export function initBluetooth(store) {
	if (!instance) instance = new BluetoothManager(store);
	return instance;
}